package com.xueqiu.movieplaymanagersystem.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xueqiu.movieplaymanagersystem.model.RequestLog;

import javax.servlet.http.HttpServletRequest;

/**
 * @author xueqiu
 * @Description: 切面增强；程序运行日志输出
 */
@Component
@Aspect
@Slf4j
public class LoggerAspect {
    private HttpServletRequest request;

    @Autowired
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    /**
     * 定义了一个切入点，表示监控所有zzuli.xueqiu.movieplaymanagersystem.controller包及其子包下的所有方法
     */
    @Pointcut("execution(* com.xueqiu.movieplaymanagersystem.controller.*.*.*(..))")
    public void joinPoints() {
    }

    /**
     * 前置通知，表示在目标方法前执行该通知，记录请求的URL、IP、方法、参数等信息
     * @param joinPoint 切入点
     */
    @Before("joinPoints()")
    public void doBefore(JoinPoint joinPoint) {
        //获取请求路径
        StringBuffer requestURL = request.getRequestURL();
        //获取ip地址
        String ipAddr = request.getRemoteAddr();
        /*
        joinPoint.getSignature().getDeclaringTypeName()获取类名
        request.getMethod()获取请求的方法名
         */
        String method = joinPoint.getSignature().getDeclaringTypeName() + " method: " + request.getMethod();
        //获取请求的参数数组
        Object[] objects = joinPoint.getArgs();
        //生成记录对象
        RequestLog requestLog = new RequestLog(
                requestURL.toString(),
                ipAddr,
                method,
                objects
        );

        log.info("Request : {}", requestLog);
    }

    /**
     * 返回通知，表示在目标方法返回后执行该通知，记录返回值
     * @param result 返回值
     */
    @AfterReturning(returning = "result", pointcut = "joinPoints()")
    public void doReturn(Object result) {
        log.info("return : {}", result);
    }

    /**
     * 异常通知，表示在目标方法抛出异常后执行该通知，记录异常信息
     * @param exception 异常信息
     */
    @AfterThrowing(throwing = "exception", pointcut = "joinPoints()")
    public void doException(Exception exception) {
        log.error("logException : ", exception);
    }

}
